package org.itboys.mobile.service.mysql.weixin.order;

import org.apache.commons.lang3.StringUtils;
import org.itboys.commons.ErrorException;
import org.itboys.commons.utils.time.TimeUtils;
import org.itboys.commons.utils.tools.ListUtil;
import org.itboys.commons.utils.tools.LongUtil;
import org.itboys.mdl.conmon.Finals;
import org.itboys.mobile.common.SundayCommonConstants;
import org.itboys.mobile.dao.order.MdlOrderProductMapper;
import org.itboys.mobile.dto.count.MdlCountDto;
import org.itboys.mobile.dto.count.MdlCountProductDto;
import org.itboys.mobile.dto.order.MdlOrderDto;
import org.itboys.mobile.dto.order.MdlOrderProductDto;
import org.itboys.mobile.entity.mongo.SundayAddress;
import org.itboys.mobile.entity.mongo.SundayMember;
import org.itboys.mobile.entity.mysql.order.MdlOrder;
import org.itboys.mobile.entity.mysql.order.MdlOrderProduct;
import org.itboys.mobile.entity.mysql.product.SundayProduct;
import org.itboys.mobile.service.mongo.web.member.SundayMemberService;
import org.itboys.mobile.service.mongo.weixin.address.SundayWeixinAddressService;
import org.itboys.mobile.service.mongo.weixin.cart.MdlWeixinCartService;
import org.itboys.mobile.service.mongo.weixin.comment.MdlWeixinCommentService;
import org.itboys.mobile.service.mongo.weixin.count.MdlWeixinCountService;
import org.itboys.mobile.util.NumberUtil;
import org.itboys.mongodb.service.BaseMySqlService;
import org.itboys.param.ParamUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

/**
 * 作者：zzq
 * 时间：2017/12/7
 * 描述：迈迪龙_微信_订单
 */
@Service
public class MdlWeixinOrderService extends BaseMySqlService<MdlOrder>{
    @Autowired
    private SundayWeixinAddressService addressService;
    @Autowired
    private MdlWeixinCountService countService;
    @Autowired
    private MdlOrderProductMapper orderProductMapper;
    @Autowired
    private MdlWeixinCartService cartService;
    @Autowired
    private SundayMemberService memberService;
    @Autowired
    private MdlWeixinCommentService commentService;
    @Transactional
    public synchronized Map<String,Object> createOrder(Long memberId,List<Long> cartIds,Integer cartType,
                                                      Long addressId,Integer sendType,
                                                       String remark){
        /**
         * 准备返回结果
         */
        Map<String,Object> result = new HashMap<String,Object>();
        BigDecimal payAmount = new BigDecimal(0);
        Integer isNeedToPay = Finals.YES;
        String orderIds ="";
        /**
         * 准备结算数据
         */
        if(!LongUtil.isNotZreo(addressId)){
            throw new ErrorException("请填写收货地址");
        }
        MdlCountDto countDto =countService.countCart( memberId,cartIds,cartType,sendType );
        SundayAddress address =addressService.getById(addressId);
        /**
         * 准备订单数据
         */
        MdlOrder order = new  MdlOrder();
        order.setOrderNo(NumberUtil.generateNumber());
        order.setRemark(remark);
        order.setType(countDto.getType());
        order.setSendType(countDto.getSendType());
        order.setTotalAmount(countDto.getTotalAmount());
        order.setPayAmount(countDto.getPayAmount());
        order.setSendAmount(countDto.getSendAmount());
        //抵扣款
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_DFK);
        order.setReceiveName(address.getReceiveName());
        order.setReceiveMobile(address.getReceiveMobile());
        order.setReceiveAddress(address.getCityName()+address.getDistrictName()+address.getReceiveAddress());

        order.setMemberName(memberService.getById(memberId).getNickName());
        order.setMemberId(memberId);
        //保存订单
        super.insert(order);
        //2017年6月8日，保存订单商品（同时保存商品的拿货和出货折扣，分类ID）
        for(MdlCountProductDto productDto:countDto.getProducts()){

            MdlOrderProduct orderProduct =

                    new MdlOrderProduct(order.getId(),productDto.getId(),
                            productDto.getPrice(),productDto.getName(),productDto.getNumber(),
                            productDto.getImage(),
                            productDto.getStandard(),productDto.getNum(), productDto.getType());
            orderProductMapper.insert(orderProduct);
        }
        //删除购物车

        if(ListUtil.isNotNull(cartIds)){
            Map<String,Object> param= new HashMap<String, Object>();
            param.put("id in", cartIds);
            cartService.delete(param);
        }
        //返回数据
        orderIds=order.getId().toString();
        payAmount=order.getPayAmount();
        result.put("payAmount", payAmount.toString());
        result.put("isNeedToPay", isNeedToPay);
        result.put("orderIds", orderIds);
        result.put("msg", "");

        return result;
    }
    /**
     * 取消订单
     * @param orderId
     * @return
     */
    public void cancelOrder(Long orderId){

        MdlOrder order= super.find(orderId);
        //用户的商城订单，待付款允许取消
        String msg=null;
        if(order.getType()==SundayCommonConstants.type_mall&&order.getOrderStatus()!=SundayCommonConstants.ORDER_STATUS_DFK){
            msg="非待付款订单，不能取消";
        }
        if(StringUtils.isNotEmpty(msg)){
            throw new ErrorException(msg);
        }
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_YQX);
        super.update(order);
    }
    /**
     * 分页获取订单
     * @param request
     * @param memberId
     * @param type, 1,采购订单，2积分订单，3，用户自己的商城订单，
     * @param orderStatuses 0，全部，1,待付款，2待配送，3配送中，4待评价，
     * @return
     */
    public List<MdlOrderDto> selectOrder(HttpServletRequest request, Long memberId, Integer type, List<Integer> orderStatuses){
        Map<String,Object> param = ParamUtil.packageMysqlPageParam(request,"orderNo","createTime_start","createTime_end");
        param.put("memberId",memberId);
        param.put("type",type);
        if(ListUtil.isNotNull(orderStatuses)){
            if(orderStatuses.get(0)!=0){
                param.put("orderStatuses",orderStatuses);
            }
        }
        return pakageDtoMuilt(super.select(param));
    }
    /**
     * 查询订单详情
     * @param orderId
     * @param memberId
     * @return
     */
    public MdlOrderDto findOne(Long orderId,Long memberId){
        return pakageDtoSingle(super.find(orderId),null);
    }

    /**
     * 评论订单
     * @param orderId
     * @param productIds
     * @param contents
     * @param scores
     * @param images 图片集合，固定大小=productIds集合大小*3。。每个商品限制最大传入三张，没有图片的使用noImage字符传固定值。
     * @param memberId
     */
    public void  commentOrder(Long orderId,List<Long> productIds,List<String> contents,List<Integer> scores,List<String> images,Long memberId){
        String msg ="";
        if(ListUtil.isNull(productIds)||ListUtil.isNull(contents)||ListUtil.isNull(scores)){
            msg="评论接口参数有错误(为空)";
        }
        if(productIds.size()!=contents.size()||productIds.size()!=scores.size()||contents.size()!=scores.size()){
            msg="评论接口参数有错误（参数不对应）";
        }
        if(productIds.size()*3!=images.size()){
            msg="评论接口参数有错误（图片参数）";
        }
        if(msg!=""){
            throw new ErrorException(msg);
        }


        MdlOrder order=checkOrder(orderId,SundayCommonConstants.ORDER_STATUS_YSH,"非待评论订单，不能评论",memberId);
        SundayMember member = memberService.getById(memberId);
        commentService.generateComment(productIds,
                contents,
                scores,
                images,
                memberId,
                member.getImage(),
                member.getNickName(),
                SundayProduct.class.getSimpleName());

        //更改订单状态
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_YPJ);
        super.update(order);

    }
    /**
     * 确认收货
     * @param orderId
     * @param memberId
     * @return
     */
    @Transactional
    public void confirmReceive(Long orderId,Long memberId){


        MdlOrder order=checkOrder(orderId,SundayCommonConstants.ORDER_STATUS_PSZ,"非配送中订单，不能确认收货",memberId);
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_YSH);
        order.setReceiveTime(new Date());

        //生成收益，
        //生成用户赠送积分(实付款+余额抵扣)
       /* if(order.getType()==SundayCommonConstants.type_mall){
            //SundayScoreConfig scoreConfig =scoreConfigService.findOne(null);
            BigDecimal thisAmount = order.getPayAmount();
            if(order.getBalancePayAmount()!=null){
                thisAmount.add(order.getBalancePayAmount());
            }
            memberService.changeScore(order.getOrderNo(),thisAmount, SundayCommonConstants.SCORE_TYPE_REWARD,memberId);
        }*/
        super.update(order);
    }
    /**
     * 校验订单信息
     * @param orderId
     * @param status
     * @param msg
     * @param memberId
     * @return
     */
    public MdlOrder checkOrder(Long orderId,Integer status,String msg,Long memberId){
        MdlOrder order =super.find(orderId);
        if(status!=null&&order.getOrderStatus()!=status){
            throw new ErrorException(msg);
        }
        if(LongUtil.isNotZreo(memberId)&&order.getMemberId().longValue()!=memberId){
            throw new ErrorException("数据错误，请重试");
        }
        return order;
    }
    /**
     * 组装DTO
     * @param order
     * @return
     */
    public MdlOrderDto pakageDtoSingle(MdlOrder order, List<MdlOrderProductDto> products){
        if(ListUtil.isNull(products)){
            Map<String,Object> param =new HashMap<String ,Object>();
            param.put("orderId",order.getId());
            products=new ArrayList<MdlOrderProductDto>();
            for(MdlOrderProduct orderProduct:orderProductMapper.select(param)){
                if(orderProduct.getOrderId().longValue()==order.getId()){
                    products.add(new MdlOrderProductDto(
                            orderProduct.getProductId(),orderProduct.getCreateTime(),orderProduct.getCreateDate(),
                            orderProduct.getPrice(), orderProduct.getName(), orderProduct.getNumber(),orderProduct.getImage(),
                            orderProduct.getStandard(), orderProduct.getNum(), orderProduct.getType()));
                }
            }

        }
        String payTime= order.getPayTime()!=null? TimeUtils.format(order.getPayTime(),"yyyy-MM-dd HH:mm:ss"):null;
        String sendTime= order.getSendTime()!=null?TimeUtils.format(order.getSendTime(),"yyyy-MM-dd HH:mm:ss"):null;
        String receiveTime= order.getReceiveTime()!=null?TimeUtils.format(order.getReceiveTime(),"yyyy-MM-dd HH:mm:ss"):null;
        return new MdlOrderDto(order.getId(),order.getCreateTime(),order.getCreateDate(),
                order.getOrderNo(), order.getType(), order.getTotalAmount(), order.getPayAmount(),
                order.getPayNo(), order.getOrderStatus(), order.getReceiveName(),order.getReceiveMobile(), order.getReceiveAddress(),
                order.getSendAmount(),order.getRemark(),
                payTime,sendTime, receiveTime,  products);

    }

    /**
     * 组装多个
     * @param orders
     * @return
     */
    public List<MdlOrderDto> pakageDtoMuilt(List<MdlOrder> orders){
        List<MdlOrderDto> dtos= new ArrayList<MdlOrderDto>();
        List<Long> orderIds = new ArrayList<>();
        for(MdlOrder order:orders){
            orderIds.add(order.getId());
        }
        Map<String,Object> param =new HashMap<String ,Object>();
        param.put("orderIds",orderIds);
        List<MdlOrderProduct> orderProducts = orderProductMapper.select(param);
        for(MdlOrder order:orders){
            List<MdlOrderProductDto> ps = new ArrayList<MdlOrderProductDto>();
            for(MdlOrderProduct orderProduct:orderProducts){
                if(orderProduct.getOrderId().longValue()==order.getId()){
                    ps.add(new MdlOrderProductDto(orderProduct.getProductId(),orderProduct.getCreateTime(),orderProduct.getCreateDate(),
                            orderProduct.getPrice(), orderProduct.getName(), orderProduct.getNumber(),orderProduct.getImage(),
                            orderProduct.getStandard(), orderProduct.getNum(), orderProduct.getType()));
                }
            }
            dtos.add(pakageDtoSingle(order,ps));
        }
        return dtos;
    }


}
